ngl: move uniform key mapping into uniform state
authorChristian Hergert <chergert@redhat.com>
Tue, 23 Mar 2021 19:10:12 +0000 (12:10 -0700)
committerChristian Hergert <chergert@redhat.com>
Tue, 23 Mar 2021 20:44:26 +0000 (13:44 -0700)
Previously, we translated the uniform key (an enum) into a location within
the shader program in GskNglProgram. A number of performance improvements
were focused around having low nubers for the uniform locations. Generally
this is the case, but some drivers such as old Intel drivers on Windows
may use rather large numbers for those.

To combat this, we can push the translation of uniform keys into locations
at the GskNglUniformState level so that we work with unranslated keys
through the process until applying them.

Fixes #3780

gsk/ngl/gsknglcommandqueue.c
gsk/ngl/gsknglcommandqueueprivate.h
gsk/ngl/gskngldriver.c
gsk/ngl/gskngldriverprivate.h
gsk/ngl/gsknglprogram.c
gsk/ngl/gsknglprogramprivate.h
gsk/ngl/gsknglrenderjob.c
gsk/ngl/gskngluniformstate.c
gsk/ngl/gskngluniformstateprivate.h

index 0fb56cfc50c90cb3e81de6653883f0da41c3f2ac..e160076c572522f0fc527c0b26a9fd3b62403a93 100644 (file)
@@ -272,24 +272,23 @@ snapshot_uniforms (GskNglUniformState    *state,
                    GskNglUniformProgram  *program,
                    GskNglCommandUniforms *array)
 {
-  GskNglCommandUniform *uniform = gsk_ngl_command_uniforms_append_n (array, program->n_sparse);
+  GskNglCommandUniform *uniform = gsk_ngl_command_uniforms_append_n (array, program->n_mappings);
   guint count = 0;
 
-  for (guint i = 0; i < program->n_sparse; i++)
+  for (guint i = 0; i < program->n_mappings; i++)
     {
-      guint location = program->sparse[i];
-      const GskNglUniformInfo *info = &program->uniforms[location].info;
+      const GskNglUniformMapping *mapping = &program->mappings[i];
 
-      if (!info->initial)
+      if (!mapping->info.initial && mapping->location > -1)
         {
-          uniform[count].location = location;
-          uniform[count].info = *info;
+          uniform[count].location = mapping->location;
+          uniform[count].info = mapping->info;
           count++;
         }
     }
 
-  if (count != program->n_sparse)
-    array->len -= program->n_sparse - count;
+  if (count != program->n_mappings)
+    array->len -= program->n_mappings - count;
 
   return count;
 }
index e51d1abb46e1a9f3f6bd8bf9bd97a4d881b10be6..bcd7c8312deb633f25bb9fdff45dcaa93748d362 100644 (file)
@@ -153,7 +153,7 @@ G_STATIC_ASSERT (sizeof (GskNglCommandClear) == 20);
 typedef struct _GskNglCommandUniform
 {
   GskNglUniformInfo info;
-  guint            location;
+  guint             location;
 } GskNglCommandUniform;
 
 G_STATIC_ASSERT (sizeof (GskNglCommandUniform) == 8);
index a4254c8da45eac2141408661c1c56221b12dfced..ec30ccf86fc4ace8b19638497221d54ac286a3e5 100644 (file)
@@ -226,14 +226,14 @@ gsk_ngl_driver_dispose (GObject *object)
 #define GSK_NGL_NO_UNIFORMS
 #define GSK_NGL_ADD_UNIFORM(pos, KEY, name)
 #define GSK_NGL_DEFINE_PROGRAM(name, resource, uniforms) \
-  GSK_NGL_DELETE_PROGRAM(name); \
-  GSK_NGL_DELETE_PROGRAM(name ## _no_clip); \
+  GSK_NGL_DELETE_PROGRAM(name);                          \
+  GSK_NGL_DELETE_PROGRAM(name ## _no_clip);              \
   GSK_NGL_DELETE_PROGRAM(name ## _rect_clip);
-#define GSK_NGL_DELETE_PROGRAM(name)                    \
-  G_STMT_START {                                        \
-    if (self->name)                                     \
+#define GSK_NGL_DELETE_PROGRAM(name)                     \
+  G_STMT_START {                                         \
+    if (self->name)                                      \
       gsk_ngl_program_delete (self->name);               \
-    g_clear_object (&self->name);                       \
+    g_clear_object (&self->name);                        \
   } G_STMT_END;
 # include "gsknglprograms.defs"
 #undef GSK_NGL_NO_UNIFORMS
@@ -356,10 +356,10 @@ gsk_ngl_driver_load_programs (GskNglDriver  *self,
 #define GSK_NGL_ADD_UNIFORM(pos, KEY, name)                                                      \
   gsk_ngl_program_add_uniform (program, #name, UNIFORM_##KEY);
 #define GSK_NGL_DEFINE_PROGRAM(name, resource, uniforms)                                         \
-   gsk_ngl_compiler_set_source_from_resource (compiler, GSK_NGL_COMPILER_ALL, resource);         \
-   GSK_NGL_COMPILE_PROGRAM(name ## _no_clip, uniforms, "#define NO_CLIP 1\n");                   \
-   GSK_NGL_COMPILE_PROGRAM(name ## _rect_clip, uniforms, "#define RECT_CLIP 1\n");               \
-   GSK_NGL_COMPILE_PROGRAM(name, uniforms, "");
+  gsk_ngl_compiler_set_source_from_resource (compiler, GSK_NGL_COMPILER_ALL, resource);          \
+  GSK_NGL_COMPILE_PROGRAM(name ## _no_clip, uniforms, "#define NO_CLIP 1\n");                    \
+  GSK_NGL_COMPILE_PROGRAM(name ## _rect_clip, uniforms, "#define RECT_CLIP 1\n");                \
+  GSK_NGL_COMPILE_PROGRAM(name, uniforms, "");
 #define GSK_NGL_COMPILE_PROGRAM(name, uniforms, clip)                                            \
   G_STMT_START {                                                                                 \
     GskNglProgram *program;                                                                      \
@@ -1046,26 +1046,26 @@ gsk_ngl_driver_lookup_shader (GskNglDriver  *self,
       int n_uniforms;
 
       uniforms = gsk_gl_shader_get_uniforms (shader, &n_uniforms);
-      if (n_uniforms > G_N_ELEMENTS (program->args_locations))
+      if (n_uniforms > GSK_NGL_PROGRAM_MAX_CUSTOM_ARGS)
         {
           g_set_error (error,
                        GDK_GL_ERROR,
                        GDK_GL_ERROR_UNSUPPORTED_FORMAT,
                        "Tried to use %d uniforms, while only %d is supported",
                        n_uniforms,
-                       (int)G_N_ELEMENTS (program->args_locations));
+                       GSK_NGL_PROGRAM_MAX_CUSTOM_ARGS);
           return NULL;
         }
 
       n_required_textures = gsk_gl_shader_get_n_textures (shader);
-      if (n_required_textures > G_N_ELEMENTS (program->texture_locations))
+      if (n_required_textures > GSK_NGL_PROGRAM_MAX_CUSTOM_TEXTURES)
         {
           g_set_error (error,
                        GDK_GL_ERROR,
                        GDK_GL_ERROR_UNSUPPORTED_FORMAT,
                        "Tried to use %d textures, while only %d is supported",
                        n_required_textures,
-                       (int)(G_N_ELEMENTS (program->texture_locations)));
+                       GSK_NGL_PROGRAM_MAX_CUSTOM_TEXTURES);
           return NULL;
         }
 
@@ -1108,18 +1108,10 @@ gsk_ngl_driver_lookup_shader (GskNglDriver  *self,
           gsk_ngl_program_add_uniform (program, "u_texture2", UNIFORM_CUSTOM_TEXTURE2);
           gsk_ngl_program_add_uniform (program, "u_texture3", UNIFORM_CUSTOM_TEXTURE3);
           gsk_ngl_program_add_uniform (program, "u_texture4", UNIFORM_CUSTOM_TEXTURE4);
-          for (guint i = 0; i < n_uniforms; i++)
-            gsk_ngl_program_add_uniform (program, uniforms[i].name, UNIFORM_CUSTOM_LAST+i);
 
-          program->size_location = gsk_ngl_program_get_uniform_location (program, UNIFORM_CUSTOM_SIZE);
-          program->texture_locations[0] = gsk_ngl_program_get_uniform_location (program, UNIFORM_CUSTOM_TEXTURE1);
-          program->texture_locations[1] = gsk_ngl_program_get_uniform_location (program, UNIFORM_CUSTOM_TEXTURE2);
-          program->texture_locations[2] = gsk_ngl_program_get_uniform_location (program, UNIFORM_CUSTOM_TEXTURE3);
-          program->texture_locations[3] = gsk_ngl_program_get_uniform_location (program, UNIFORM_CUSTOM_TEXTURE4);
+          /* Custom arguments (max is 8) */
           for (guint i = 0; i < n_uniforms; i++)
-            program->args_locations[i] = gsk_ngl_program_get_uniform_location (program, UNIFORM_CUSTOM_LAST+i);
-          for (guint i = n_uniforms; i < G_N_ELEMENTS (program->args_locations); i++)
-            program->args_locations[i] = -1;
+            gsk_ngl_program_add_uniform (program, uniforms[i].name, UNIFORM_CUSTOM_ARG0+i);
 
           gsk_ngl_program_uniforms_added (program, TRUE);
 
index c50e112e862690be16d5b9e3409f64f47184ae07..ad9b4a0ff2423d6d8e848fa01054402ce18f952a 100644 (file)
@@ -45,6 +45,14 @@ enum {
   UNIFORM_CUSTOM_TEXTURE2,
   UNIFORM_CUSTOM_TEXTURE3,
   UNIFORM_CUSTOM_TEXTURE4,
+  UNIFORM_CUSTOM_ARG0,
+  UNIFORM_CUSTOM_ARG1,
+  UNIFORM_CUSTOM_ARG2,
+  UNIFORM_CUSTOM_ARG3,
+  UNIFORM_CUSTOM_ARG4,
+  UNIFORM_CUSTOM_ARG5,
+  UNIFORM_CUSTOM_ARG6,
+  UNIFORM_CUSTOM_ARG7,
 
   UNIFORM_CUSTOM_LAST
 };
index 1343eb35a472c2c5bf7475740c5159dc6fa7d65b..d6db23fad8737b2ef60eb2690c6a9c48ea8d852c 100644 (file)
@@ -40,7 +40,7 @@ gsk_ngl_program_new (GskNglDriver *driver,
   self->id = program_id;
   self->name = g_strdup (name);
   self->driver = g_object_ref (driver);
-  self->n_uniforms = 0;
+  self->n_mappings = 0;
 
   return self;
 }
@@ -74,8 +74,8 @@ gsk_ngl_program_init (GskNglProgram *self)
 {
   self->id = -1;
 
-  for (guint i = 0; i < G_N_ELEMENTS (self->uniform_locations); i++)
-    self->uniform_locations[i] = -1;
+  for (guint i = 0; i < G_N_ELEMENTS (self->mappings); i++)
+    self->mappings[i].location = -1;
 }
 
 /**
@@ -114,22 +114,22 @@ gsk_ngl_program_add_uniform (GskNglProgram *self,
 
   g_return_val_if_fail (GSK_IS_NGL_PROGRAM (self), FALSE);
   g_return_val_if_fail (name != NULL, FALSE);
-  g_return_val_if_fail (key < 1024, FALSE);
+  g_return_val_if_fail (key < G_N_ELEMENTS (self->mappings), FALSE);
 
-  if (-1 == (location = glGetUniformLocation (self->id, name)))
-    return FALSE;
+  location = glGetUniformLocation (self->id, name);
 
-  self->uniform_locations[key] = location;
-
-  if (location >= self->n_uniforms)
-    self->n_uniforms = location + 1;
+  /* Register the information even if unused */
+  self->mappings[key].name = g_intern_string (name);
+  self->mappings[key].location = location;
+  if (key >= self->n_mappings)
+    self->n_mappings = key + 1;
 
 #if 0
-  g_print ("program [%d] %s uniform %s at location %d.\n",
-           self->id, self->name, name, location);
+  g_print ("program [%d] %s uniform %s [%u of %u] at location %d.\n",
+           self->id, self->name, name, key, self->n_mappings, location);
 #endif
 
-  return TRUE;
+  return location > -1;
 }
 
 /**
@@ -171,6 +171,6 @@ gsk_ngl_program_uniforms_added (GskNglProgram *self,
   g_return_if_fail (self->uniforms == NULL);
 
   self->uniforms = self->driver->command_queue->uniforms;
-  self->program_info = gsk_ngl_uniform_state_get_program (self->uniforms, self->id, self->n_uniforms);
+  self->program_info = gsk_ngl_uniform_state_get_program (self->uniforms, self->id, self->mappings, self->n_mappings);
   self->program_info->has_attachments = has_attachments;
 }
index 47bb0e314fe65691648d21676d4135884ec06ed3..ccf0b8a7984923d5a640221e5dffdf11bf3532b2 100644 (file)
 
 #include "gskngltypesprivate.h"
 
+#include "gsknglattachmentstateprivate.h"
 #include "gsknglcommandqueueprivate.h"
 #include "gskngldriverprivate.h"
 
 G_BEGIN_DECLS
 
 #define GSK_TYPE_GL_PROGRAM (gsk_ngl_program_get_type())
+#define GSK_NGL_PROGRAM_MAX_CUSTOM_TEXTURES 4
+#define GSK_NGL_PROGRAM_MAX_CUSTOM_ARGS 8
 
 G_DECLARE_FINAL_TYPE (GskNglProgram, gsk_ngl_program, GSK, NGL_PROGRAM, GObject)
 
@@ -40,23 +43,13 @@ struct _GskNglProgram
   char *name;
   GskNglDriver *driver;
 
-  /* In reality, this is the largest uniform position
-   * as returned after linking so that we can use direct
-   * indexes based on location.
-   */
-  guint n_uniforms;
-
   /* Cached pointer to avoid lots of pointer chasing/lookups */
   GskNglUniformState *uniforms;
   GskNglUniformProgram *program_info;
 
-  /* For custom programs */
-  int texture_locations[4];
-  int args_locations[8];
-  int size_location;
-
   /* Static array for key->location transforms */
-  int uniform_locations[32];
+  GskNglUniformMapping mappings[32];
+  guint n_mappings;
 };
 
 GskNglProgram *gsk_ngl_program_new            (GskNglDriver  *driver,
@@ -69,8 +62,6 @@ void           gsk_ngl_program_uniforms_added (GskNglProgram *self,
                                                gboolean       has_attachments);
 void           gsk_ngl_program_delete         (GskNglProgram *self);
 
-#define gsk_ngl_program_get_uniform_location(s,k) ((s)->uniform_locations[(k)])
-
 static inline void
 gsk_ngl_program_set_uniform1fv (GskNglProgram *self,
                                 guint          key,
@@ -79,8 +70,10 @@ gsk_ngl_program_set_uniform1fv (GskNglProgram *self,
                                 const float   *values)
 {
   gsk_ngl_uniform_state_set1fv (self->uniforms, self->program_info,
-                                gsk_ngl_program_get_uniform_location (self, key),
-                                stamp, count, values);
+                                key,
+                                stamp,
+                                count,
+                                values);
 }
 
 static inline void
@@ -91,8 +84,10 @@ gsk_ngl_program_set_uniform2fv (GskNglProgram *self,
                                 const float   *values)
 {
   gsk_ngl_uniform_state_set2fv (self->uniforms, self->program_info,
-                                gsk_ngl_program_get_uniform_location (self, key),
-                                stamp, count, values);
+                                key,
+                                stamp,
+                                count,
+                                values);
 }
 
 static inline void
@@ -103,8 +98,10 @@ gsk_ngl_program_set_uniform4fv (GskNglProgram *self,
                                 const float   *values)
 {
   gsk_ngl_uniform_state_set4fv (self->uniforms, self->program_info,
-                                gsk_ngl_program_get_uniform_location (self, key),
-                                stamp, count, values);
+                                key,
+                                stamp,
+                                count,
+                                values);
 }
 
 static inline void
@@ -114,8 +111,9 @@ gsk_ngl_program_set_uniform_rounded_rect (GskNglProgram        *self,
                                           const GskRoundedRect *rounded_rect)
 {
   gsk_ngl_uniform_state_set_rounded_rect (self->uniforms, self->program_info,
-                                          gsk_ngl_program_get_uniform_location (self, key),
-                                          stamp, rounded_rect);
+                                          key,
+                                          stamp,
+                                          rounded_rect);
 }
 
 static inline void
@@ -126,8 +124,9 @@ gsk_ngl_program_set_uniform1i (GskNglProgram *self,
 {
   gsk_ngl_uniform_state_set1i (self->uniforms,
                                self->program_info,
-                               gsk_ngl_program_get_uniform_location (self, key),
-                               stamp, value0);
+                               key,
+                               stamp,
+                               value0);
 }
 
 static inline void
@@ -139,8 +138,9 @@ gsk_ngl_program_set_uniform2i (GskNglProgram *self,
 {
   gsk_ngl_uniform_state_set2i (self->uniforms,
                                self->program_info,
-                               gsk_ngl_program_get_uniform_location (self, key),
-                               stamp, value0, value1);
+                               key,
+                               stamp,
+                               value0, value1);
 }
 
 static inline void
@@ -153,8 +153,9 @@ gsk_ngl_program_set_uniform3i (GskNglProgram *self,
 {
   gsk_ngl_uniform_state_set3i (self->uniforms,
                                self->program_info,
-                               gsk_ngl_program_get_uniform_location (self, key),
-                               stamp, value0, value1, value2);
+                               key,
+                               stamp,
+                               value0, value1, value2);
 }
 
 static inline void
@@ -168,8 +169,9 @@ gsk_ngl_program_set_uniform4i (GskNglProgram *self,
 {
   gsk_ngl_uniform_state_set4i (self->uniforms,
                                self->program_info,
-                               gsk_ngl_program_get_uniform_location (self, key),
-                               stamp, value0, value1, value2, value3);
+                               key,
+                               stamp,
+                               value0, value1, value2, value3);
 }
 
 static inline void
@@ -180,8 +182,9 @@ gsk_ngl_program_set_uniform1f (GskNglProgram *self,
 {
   gsk_ngl_uniform_state_set1f (self->uniforms,
                                self->program_info,
-                               gsk_ngl_program_get_uniform_location (self, key),
-                               stamp, value0);
+                               key,
+                               stamp,
+                               value0);
 }
 
 static inline void
@@ -193,8 +196,9 @@ gsk_ngl_program_set_uniform2f (GskNglProgram *self,
 {
   gsk_ngl_uniform_state_set2f (self->uniforms,
                                self->program_info,
-                               gsk_ngl_program_get_uniform_location (self, key),
-                               stamp, value0, value1);
+                               key,
+                               stamp,
+                               value0, value1);
 }
 
 static inline void
@@ -207,8 +211,9 @@ gsk_ngl_program_set_uniform3f (GskNglProgram *self,
 {
   gsk_ngl_uniform_state_set3f (self->uniforms,
                                self->program_info,
-                               gsk_ngl_program_get_uniform_location (self, key),
-                               stamp, value0, value1, value2);
+                               key,
+                               stamp,
+                               value0, value1, value2);
 }
 
 static inline void
@@ -222,8 +227,9 @@ gsk_ngl_program_set_uniform4f (GskNglProgram *self,
 {
   gsk_ngl_uniform_state_set4f (self->uniforms,
                                self->program_info,
-                               gsk_ngl_program_get_uniform_location (self, key),
-                               stamp, value0, value1, value2, value3);
+                               key,
+                               stamp,
+                               value0, value1, value2, value3);
 }
 
 static inline void
@@ -234,8 +240,9 @@ gsk_ngl_program_set_uniform_color (GskNglProgram *self,
 {
   gsk_ngl_uniform_state_set_color (self->uniforms,
                                    self->program_info,
-                                   gsk_ngl_program_get_uniform_location (self, key),
-                                   stamp, color);
+                                   key,
+                                   stamp,
+                                   color);
 }
 
 static inline void
@@ -252,8 +259,9 @@ gsk_ngl_program_set_uniform_texture (GskNglProgram *self,
                                          texture_id);
   gsk_ngl_uniform_state_set_texture (self->uniforms,
                                      self->program_info,
-                                     gsk_ngl_program_get_uniform_location (self, key),
-                                     stamp, texture_slot);
+                                     key,
+                                     stamp,
+                                     texture_slot);
 }
 
 static inline void
@@ -264,8 +272,9 @@ gsk_ngl_program_set_uniform_matrix (GskNglProgram           *self,
 {
   gsk_ngl_uniform_state_set_matrix (self->uniforms,
                                     self->program_info,
-                                    gsk_ngl_program_get_uniform_location (self, key),
-                                    stamp, matrix);
+                                    key,
+                                    stamp,
+                                    matrix);
 }
 
 G_END_DECLS
index f6cf7383538e6a16b2825e660013db4012349de6..8e4246d8b79d609c4fe0e62789da6d0f04df09c3 100644 (file)
@@ -1003,41 +1003,36 @@ gsk_ngl_render_job_begin_draw (GskNglRenderJob *job,
                                     job->viewport.size.width,
                                     job->viewport.size.height);
 
-  if (program->uniform_locations[UNIFORM_SHARED_VIEWPORT] > -1)
-    gsk_ngl_uniform_state_set4fv (program->uniforms,
-                                  program->program_info,
-                                  program->uniform_locations[UNIFORM_SHARED_VIEWPORT],
-                                  job->driver->stamps[UNIFORM_SHARED_VIEWPORT],
-                                  1,
-                                  (const float *)&job->viewport);
-
-  if (program->uniform_locations[UNIFORM_SHARED_MODELVIEW] > -1)
-    gsk_ngl_uniform_state_set_matrix (program->uniforms,
-                                      program->program_info,
-                                      program->uniform_locations[UNIFORM_SHARED_MODELVIEW],
-                                      job->driver->stamps[UNIFORM_SHARED_MODELVIEW],
-                                      &job->current_modelview->matrix);
-
-  if (program->uniform_locations[UNIFORM_SHARED_PROJECTION] > -1)
-    gsk_ngl_uniform_state_set_matrix (program->uniforms,
-                                      program->program_info,
-                                      program->uniform_locations[UNIFORM_SHARED_PROJECTION],
-                                      job->driver->stamps[UNIFORM_SHARED_PROJECTION],
-                                      &job->projection);
-
-  if (program->uniform_locations[UNIFORM_SHARED_CLIP_RECT] > -1)
-    gsk_ngl_uniform_state_set_rounded_rect (program->uniforms,
-                                            program->program_info,
-                                            program->uniform_locations[UNIFORM_SHARED_CLIP_RECT],
-                                            job->driver->stamps[UNIFORM_SHARED_CLIP_RECT],
-                                            &job->current_clip->rect);
+  gsk_ngl_uniform_state_set4fv (program->uniforms,
+                                program->program_info,
+                                UNIFORM_SHARED_VIEWPORT,
+                                job->driver->stamps[UNIFORM_SHARED_VIEWPORT],
+                                1,
+                                (const float *)&job->viewport);
+
+  gsk_ngl_uniform_state_set_matrix (program->uniforms,
+                                    program->program_info,
+                                    UNIFORM_SHARED_MODELVIEW,
+                                    job->driver->stamps[UNIFORM_SHARED_MODELVIEW],
+                                    &job->current_modelview->matrix);
 
-  if (program->uniform_locations[UNIFORM_SHARED_ALPHA] > -1)
-    gsk_ngl_uniform_state_set1f (program->uniforms,
-                                 program->program_info,
-                                 program->uniform_locations[UNIFORM_SHARED_ALPHA],
-                                 job->driver->stamps[UNIFORM_SHARED_ALPHA],
-                                 job->alpha);
+  gsk_ngl_uniform_state_set_matrix (program->uniforms,
+                                    program->program_info,
+                                    UNIFORM_SHARED_PROJECTION,
+                                    job->driver->stamps[UNIFORM_SHARED_PROJECTION],
+                                    &job->projection);
+
+  gsk_ngl_uniform_state_set_rounded_rect (program->uniforms,
+                                          program->program_info,
+                                          UNIFORM_SHARED_CLIP_RECT,
+                                          job->driver->stamps[UNIFORM_SHARED_CLIP_RECT],
+                                          &job->current_clip->rect);
+
+  gsk_ngl_uniform_state_set1f (program->uniforms,
+                               program->program_info,
+                               UNIFORM_SHARED_ALPHA,
+                               job->driver->stamps[UNIFORM_SHARED_ALPHA],
+                               job->alpha);
 }
 
 #define CHOOSE_PROGRAM(job,name) \
@@ -3086,10 +3081,6 @@ gsk_ngl_render_job_visit_gl_shader_node (GskNglRenderJob     *job,
           const GskGLUniform *u = &uniforms[i];
           const guint8 *data = base + u->offset;
 
-          /* Ignore unused uniforms */
-          if (program->args_locations[i] == -1)
-            continue;
-
           switch (u->type)
             {
             default:
@@ -3098,38 +3089,38 @@ gsk_ngl_render_job_visit_gl_shader_node (GskNglRenderJob     *job,
             case GSK_GL_UNIFORM_TYPE_FLOAT:
               gsk_ngl_uniform_state_set1fv (job->command_queue->uniforms,
                                             program->program_info,
-                                            program->args_locations[i],
+                                            UNIFORM_CUSTOM_ARG0 + i,
                                             0, 1, (const float *)data);
               break;
             case GSK_GL_UNIFORM_TYPE_INT:
               gsk_ngl_uniform_state_set1i (job->command_queue->uniforms,
                                            program->program_info,
-                                           program->args_locations[i],
+                                           UNIFORM_CUSTOM_ARG0 + i,
                                            0, *(const gint32 *)data);
               break;
             case GSK_GL_UNIFORM_TYPE_UINT:
             case GSK_GL_UNIFORM_TYPE_BOOL:
               gsk_ngl_uniform_state_set1ui (job->command_queue->uniforms,
                                             program->program_info,
-                                            program->args_locations[i],
+                                            UNIFORM_CUSTOM_ARG0 + i,
                                             0, *(const guint32 *)data);
               break;
             case GSK_GL_UNIFORM_TYPE_VEC2:
               gsk_ngl_uniform_state_set2fv (job->command_queue->uniforms,
                                             program->program_info,
-                                            program->args_locations[i],
+                                            UNIFORM_CUSTOM_ARG0 + i,
                                             0, 1, (const float *)data);
               break;
             case GSK_GL_UNIFORM_TYPE_VEC3:
               gsk_ngl_uniform_state_set3fv (job->command_queue->uniforms,
                                             program->program_info,
-                                            program->args_locations[i],
+                                            UNIFORM_CUSTOM_ARG0 + i,
                                             0, 1, (const float *)data);
               break;
             case GSK_GL_UNIFORM_TYPE_VEC4:
               gsk_ngl_uniform_state_set4fv (job->command_queue->uniforms,
                                             program->program_info,
-                                            program->args_locations[i],
+                                            UNIFORM_CUSTOM_ARG0 + i,
                                             0, 1, (const float *)data);
               break;
             }
index c6fc9b5b67cb229f8cde261afe0464df1f044871..44270e8fa5482a920a6f4a7a0b966e56afbb6a0e 100644 (file)
@@ -92,14 +92,14 @@ gsk_ngl_uniform_state_unref (GskNglUniformState *state)
 }
 
 gpointer
-gsk_ngl_uniform_state_init_value (GskNglUniformState        *state,
-                                  GskNglUniformProgram      *program,
-                                  GskNglUniformFormat        format,
-                                  guint                      array_count,
-                                  guint                      location,
-                                  GskNglUniformInfoElement **infoptr)
+gsk_ngl_uniform_state_init_value (GskNglUniformState    *state,
+                                  GskNglUniformProgram  *program,
+                                  GskNglUniformFormat    format,
+                                  guint                  array_count,
+                                  guint                  key,
+                                  GskNglUniformMapping **infoptr)
 {
-  GskNglUniformInfoElement *info;
+  GskNglUniformMapping *mapping;
   guint offset;
 
   g_assert (state != NULL);
@@ -107,23 +107,22 @@ gsk_ngl_uniform_state_init_value (GskNglUniformState        *state,
   g_assert ((int)format >= 0 && format < GSK_NGL_UNIFORM_FORMAT_LAST);
   g_assert (format > 0);
   g_assert (program != NULL);
-  g_assert (program->sparse != NULL);
-  g_assert (program->n_sparse <= program->n_uniforms);
-  g_assert (location < GL_MAX_UNIFORM_LOCATIONS || location == (guint)-1);
-  g_assert (location < program->n_uniforms);
+  g_assert (key < program->n_mappings);
 
-  /* Handle unused uniforms gracefully */
-  if G_UNLIKELY (location == (guint)-1)
-    return NULL;
+  mapping = &program->mappings[key];
 
-  info = &program->uniforms[location];
+  if (mapping->location == -1)
+    {
+      *infoptr = NULL;
+      return NULL;
+    }
 
-  if G_LIKELY (format == info->info.format)
+  if G_LIKELY (format == mapping->info.format)
     {
-      if G_LIKELY (array_count <= info->info.array_count)
+      if G_LIKELY (array_count <= mapping->info.array_count)
         {
-          *infoptr = info;
-          return GSK_NGL_UNIFORM_VALUE (state->values_buf, info->info.offset);
+          *infoptr = mapping;
+          return GSK_NGL_UNIFORM_VALUE (state->values_buf, mapping->info.offset);
         }
 
       /* We found the uniform, but there is not enough space for the
@@ -136,7 +135,7 @@ gsk_ngl_uniform_state_init_value (GskNglUniformState        *state,
        */
       goto setup_info;
     }
-  else if (info->info.format == 0)
+  else if (mapping->info.format == 0)
     {
       goto setup_info;
     }
@@ -145,8 +144,8 @@ gsk_ngl_uniform_state_init_value (GskNglUniformState        *state,
       g_critical ("Attempt to access uniform with different type of value "
                   "than it was initialized with. Program %u Location %u. "
                   "Was %d now %d (array length %d now %d).",
-                  program->program_id, location, info->info.format, format,
-                  info->info.array_count, array_count);
+                  program->program_id, key, mapping->info.format, format,
+                  mapping->info.array_count, array_count);
       *infoptr = NULL;
       return NULL;
     }
@@ -160,22 +159,15 @@ setup_info:
   /* we have 21 bits for offset */
   g_assert (offset < (1 << GSK_NGL_UNIFORM_OFFSET_BITS));
 
-  /* We could once again be setting up this info if the array size grew.
-   * So make sure that we have space in our space array for the value.
-   */
-  g_assert (info->info.format != 0 || program->n_sparse < program->n_uniforms);
-  if (info->info.format == 0)
-    program->sparse[program->n_sparse++] = location;
-
-  info->info.format = format;
-  info->info.offset = offset;
-  info->info.array_count = array_count;
-  info->info.initial = TRUE;
-  info->stamp = 0;
+  mapping->info.format = format;
+  mapping->info.offset = offset;
+  mapping->info.array_count = array_count;
+  mapping->info.initial = TRUE;
+  mapping->stamp = 0;
 
-  *infoptr = info;
+  *infoptr = mapping;
 
-  return GSK_NGL_UNIFORM_VALUE (state->values_buf, info->info.offset);
+  return GSK_NGL_UNIFORM_VALUE (state->values_buf, mapping->info.offset);
 }
 
 void
@@ -196,24 +188,25 @@ gsk_ngl_uniform_state_end_frame (GskNglUniformState *state)
   g_hash_table_iter_init (&iter, state->programs);
   while (g_hash_table_iter_next (&iter, NULL, (gpointer *)&program))
     {
-      for (guint j = 0; j < program->n_sparse; j++)
+      for (guint j = 0; j < program->n_mappings; j++)
         {
-          guint location = program->sparse[j];
-          GskNglUniformInfoElement *info = &program->uniforms[location];
+          GskNglUniformMapping *mapping = &program->mappings[j];
           guint size;
 
-          g_assert (info->info.format > 0);
+          /* Skip unused uniform mappings */
+          if (mapping->info.format == 0 || mapping->location == -1)
+            continue;
 
           /* Calculate how much size is needed for the uniform, including arrays */
-          size = uniform_sizes[info->info.format] * MAX (1, info->info.array_count);
+          size = uniform_sizes[mapping->info.format] * MAX (1, mapping->info.array_count);
 
           /* Adjust alignment for value */
           allocator += gsk_ngl_uniform_state_align (allocator, size);
 
           /* Offset is in slots of 4 bytes */
-          info->info.offset = allocator / 4;
-          info->info.initial = TRUE;
-          info->stamp = 0;
+          mapping->info.offset = allocator / 4;
+          mapping->info.initial = TRUE;
+          mapping->stamp = 0;
 
           /* Now advance for this items data */
           allocator += size;
@@ -237,35 +230,27 @@ gsk_ngl_uniform_format_size (GskNglUniformFormat format)
 }
 
 GskNglUniformProgram *
-gsk_ngl_uniform_state_get_program (GskNglUniformState *state,
-                                   guint               program,
-                                   guint               n_uniforms)
+gsk_ngl_uniform_state_get_program (GskNglUniformState         *state,
+                                   guint                       program,
+                                   const GskNglUniformMapping *mappings,
+                                   guint                       n_mappings)
 {
   GskNglUniformProgram *ret;
 
   g_return_val_if_fail (state != NULL, NULL);
   g_return_val_if_fail (program > 0, NULL);
   g_return_val_if_fail (program < G_MAXUINT, NULL);
+  g_return_val_if_fail (n_mappings <= G_N_ELEMENTS (ret->mappings), NULL);
 
   ret = g_hash_table_lookup (state->programs, GUINT_TO_POINTER (program));
 
   if (ret == NULL)
     {
-      gsize uniform_size = n_uniforms * sizeof (GskNglUniformInfoElement);
-      gsize sparse_size = n_uniforms * sizeof (guint);
-      gsize size = sizeof (GskNglUniformProgram) + uniform_size + sparse_size;
-
-      /* Must be multiple of 4 for space pointer to align */
-      G_STATIC_ASSERT (sizeof (GskNglUniformInfoElement) == 8);
-
-      ret = g_malloc0 (size);
+      ret = g_new0 (GskNglUniformProgram, 1);
       ret->program_id = program;
-      ret->n_uniforms = n_uniforms;
-      ret->n_sparse = 0;
-      ret->sparse = (guint *)&ret->uniforms[n_uniforms];
+      ret->n_mappings = n_mappings;
 
-      for (guint i = 0; i < n_uniforms; i++)
-        ret->uniforms[i].info.initial = TRUE;
+      memcpy (ret->mappings, mappings, n_mappings * sizeof *mappings);
 
       g_hash_table_insert (state->programs, GUINT_TO_POINTER (program), ret);
     }
index fe2852f68fc28cbfaf3b9e0483707c28eb850ea1..be36c6e88a280d09016815da38a89c56e9232f27 100644 (file)
@@ -51,30 +51,21 @@ typedef struct _GskNglUniformInfo
 
 G_STATIC_ASSERT (sizeof (GskNglUniformInfo) == 4);
 
-typedef struct _GskNglUniformInfoElement
+typedef struct _GskNglUniformMapping
 {
+  const char *name;
   GskNglUniformInfo info;
   guint stamp;
-} GskNglUniformInfoElement;
-
-G_STATIC_ASSERT (sizeof (GskNglUniformInfoElement) == 8);
+  int location;
+} GskNglUniformMapping;
 
 typedef struct _GskNglUniformProgram
 {
   guint program_id;
   guint n_uniforms : 12;
   guint has_attachments : 1;
-
-  /* To avoid walking our 1:1 array of location->uniform slots, we have
-   * a sparse index that allows us to skip the empty zones.
-   */
-  guint *sparse;
-  guint n_sparse;
-
-  /* Uniforms are provided inline at the end of structure to avoid
-   * an extra dereference.
-   */
-  GskNglUniformInfoElement uniforms[0];
+  guint n_mappings;
+  GskNglUniformMapping mappings[32];
 } GskNglUniformProgram;
 
 typedef struct _GskNglUniformState
@@ -86,20 +77,6 @@ typedef struct _GskNglUniformState
   GskNglUniformInfo apply_hash[512];
 } GskNglUniformState;
 
-/**
- * GskNglUniformStateCallback:
- * @info: a pointer to the information about the uniform
- * @location: the location of the uniform within the GPU program.
- * @user_data: closure data for the callback
- *
- * This callback can be used to snapshot state of a program which
- * is useful when batching commands so that the state may be compared
- * with future evocations of the program.
- */
-typedef void (*GskNglUniformStateCallback) (const GskNglUniformInfo *info,
-                                            guint                    location,
-                                            gpointer                 user_data);
-
 typedef enum _GskNglUniformKind
 {
   GSK_NGL_UNIFORM_FORMAT_1F = 1,
@@ -131,49 +108,42 @@ typedef enum _GskNglUniformKind
 G_STATIC_ASSERT (GSK_NGL_UNIFORM_FORMAT_LAST < (1 << GSK_NGL_UNIFORM_FORMAT_BITS));
 
 GskNglUniformState   *gsk_ngl_uniform_state_new         (void);
-GskNglUniformState   *gsk_ngl_uniform_state_ref         (GskNglUniformState        *state);
-void                  gsk_ngl_uniform_state_unref       (GskNglUniformState        *state);
-GskNglUniformProgram *gsk_ngl_uniform_state_get_program (GskNglUniformState        *state,
-                                                         guint                      program,
-                                                         guint                      n_uniforms);
-void                  gsk_ngl_uniform_state_end_frame   (GskNglUniformState        *state);
-gsize                 gsk_ngl_uniform_format_size       (GskNglUniformFormat        format);
-gpointer              gsk_ngl_uniform_state_init_value  (GskNglUniformState        *state,
-                                                         GskNglUniformProgram      *program,
-                                                         GskNglUniformFormat        format,
-                                                         guint                      array_count,
-                                                         guint                      location,
-                                                         GskNglUniformInfoElement **infoptr);
+GskNglUniformState   *gsk_ngl_uniform_state_ref         (GskNglUniformState          *state);
+void                  gsk_ngl_uniform_state_unref       (GskNglUniformState          *state);
+GskNglUniformProgram *gsk_ngl_uniform_state_get_program (GskNglUniformState          *state,
+                                                         guint                        program,
+                                                         const GskNglUniformMapping  *mappings,
+                                                         guint                        n_mappings);
+void                  gsk_ngl_uniform_state_end_frame   (GskNglUniformState          *state);
+gsize                 gsk_ngl_uniform_format_size       (GskNglUniformFormat          format);
+gpointer              gsk_ngl_uniform_state_init_value  (GskNglUniformState          *state,
+                                                         GskNglUniformProgram        *program,
+                                                         GskNglUniformFormat          format,
+                                                         guint                        array_count,
+                                                         guint                        key,
+                                                         GskNglUniformMapping       **out_mapping);
 
 #define GSK_NGL_UNIFORM_VALUE(base, offset) ((gpointer)((base) + ((offset) * 4)))
 #define gsk_ngl_uniform_state_get_uniform_data(state,offset) GSK_NGL_UNIFORM_VALUE((state)->values_buf, offset)
-#define gsk_ngl_uniform_state_snapshot(state, program_info, callback, user_data) \
-  G_STMT_START {                                                                 \
-    for (guint z = 0; z < program_info->n_sparse; z++)                           \
-      {                                                                          \
-        guint location = program_info->sparse[z];                                \
-        GskNglUniformInfoElement *info = &program_info->uniforms[location];      \
-                                                                                 \
-        g_assert (location < GL_MAX_UNIFORM_LOCATIONS);                          \
-        g_assert (location < program_info->n_uniforms);                          \
-                                                                                 \
-        if (info->info.format > 0)                                               \
-          callback (&info->info, location, user_data);                           \
-      }                                                                          \
-  } G_STMT_END
 
 static inline gpointer
-gsk_ngl_uniform_state_get_value (GskNglUniformState        *state,
-                                 GskNglUniformProgram      *program,
-                                 GskNglUniformFormat        format,
-                                 guint                      array_count,
-                                 guint                      location,
-                                 guint                      stamp,
-                                 GskNglUniformInfoElement **infoptr)
+gsk_ngl_uniform_state_get_value (GskNglUniformState    *state,
+                                 GskNglUniformProgram  *program,
+                                 GskNglUniformFormat    format,
+                                 guint                  array_count,
+                                 guint                  key,
+                                 guint                  stamp,
+                                 GskNglUniformMapping **out_mapping)
 {
-  GskNglUniformInfoElement *info;
+  GskNglUniformMapping *mapping;
+
+  g_assert (key < G_N_ELEMENTS (program->mappings));
+  g_assert (key < program->n_mappings);
+
+  mapping = &program->mappings[key];
 
-  if (location == (guint)-1)
+  /* Short-circuit if the program optimized the uniform out */
+  if (mapping->location == -1)
     return NULL;
 
   /* If the stamp is the same, then we can ignore the request
@@ -185,17 +155,16 @@ gsk_ngl_uniform_state_get_value (GskNglUniformState        *state,
    * modelview, clip, etc to avoid so many comparisons which cost
    * considerable CPU.
    */
-  info = &program->uniforms[location];
-  if (stamp != 0 && stamp == info->stamp)
+  if (stamp != 0 && stamp == mapping->stamp)
     return NULL;
 
-  if G_LIKELY (format == info->info.format && array_count <= info->info.array_count)
+  if G_LIKELY (format == mapping->info.format && array_count <= mapping->info.array_count)
     {
-      *infoptr = info;
-      return GSK_NGL_UNIFORM_VALUE (state->values_buf, info->info.offset);
+      *out_mapping = mapping;
+      return GSK_NGL_UNIFORM_VALUE (state->values_buf, mapping->info.offset);
     }
 
-  return gsk_ngl_uniform_state_init_value (state, program, format, array_count, location, infoptr);
+  return gsk_ngl_uniform_state_init_value (state, program, format, array_count, key, out_mapping);
 }
 
 static inline guint
@@ -251,8 +220,7 @@ gsk_ngl_uniform_state_realloc (GskNglUniformState *state,
   } G_STMT_END
 
 static inline void
-gsk_ngl_uniform_info_changed (GskNglUniformInfoElement *info,
-                              guint                     location,
+gsk_ngl_uniform_info_changed (GskNglUniformMapping *info,
                               guint                     stamp)
 {
   info->stamp = stamp;
@@ -262,23 +230,23 @@ gsk_ngl_uniform_info_changed (GskNglUniformInfoElement *info,
 static inline void
 gsk_ngl_uniform_state_set1f (GskNglUniformState   *state,
                              GskNglUniformProgram *program,
-                             guint                 location,
+                             guint                 key,
                              guint                 stamp,
                              float                 value0)
 {
   Uniform1f *u;
-  GskNglUniformInfoElement *info;
+  GskNglUniformMapping *info;
 
   g_assert (state != NULL);
   g_assert (program != 0);
 
-  if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_1F, 1, location, stamp, &info)))
+  if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_1F, 1, key, stamp, &info)))
     {
       if (info->info.initial || u->v0 != value0)
         {
           GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform1f , 1);
           u->v0 = value0;
-          gsk_ngl_uniform_info_changed (info, location, stamp);
+          gsk_ngl_uniform_info_changed (info, stamp);
         }
     }
 }
@@ -286,25 +254,25 @@ gsk_ngl_uniform_state_set1f (GskNglUniformState   *state,
 static inline void
 gsk_ngl_uniform_state_set2f (GskNglUniformState   *state,
                              GskNglUniformProgram *program,
-                             guint                 location,
+                             guint                 key,
                              guint                 stamp,
                              float                 value0,
                              float                 value1)
 {
   Uniform2f *u;
-  GskNglUniformInfoElement *info;
+  GskNglUniformMapping *info;
 
   g_assert (state != NULL);
   g_assert (program != NULL);
 
-  if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_2F, 1, location, stamp, &info)))
+  if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_2F, 1, key, stamp, &info)))
     {
       if (info->info.initial || u->v0 != value0 || u->v1 != value1)
         {
           GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform2f, 1);
           u->v0 = value0;
           u->v1 = value1;
-          gsk_ngl_uniform_info_changed (info, location, stamp);
+          gsk_ngl_uniform_info_changed (info, stamp);
         }
     }
 }
@@ -312,19 +280,19 @@ gsk_ngl_uniform_state_set2f (GskNglUniformState   *state,
 static inline void
 gsk_ngl_uniform_state_set3f (GskNglUniformState   *state,
                              GskNglUniformProgram *program,
-                             guint                 location,
+                             guint                 key,
                              guint                 stamp,
                              float                 value0,
                              float                 value1,
                              float                 value2)
 {
   Uniform3f *u;
-  GskNglUniformInfoElement *info;
+  GskNglUniformMapping *info;
 
   g_assert (state != NULL);
   g_assert (program != NULL);
 
-  if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_3F, 1, location, stamp, &info)))
+  if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_3F, 1, key, stamp, &info)))
     {
       if (info->info.initial || u->v0 != value0 || u->v1 != value1 || u->v2 != value2)
         {
@@ -332,7 +300,7 @@ gsk_ngl_uniform_state_set3f (GskNglUniformState   *state,
           u->v0 = value0;
           u->v1 = value1;
           u->v2 = value2;
-          gsk_ngl_uniform_info_changed (info, location, stamp);
+          gsk_ngl_uniform_info_changed (info, stamp);
         }
     }
 }
@@ -340,7 +308,7 @@ gsk_ngl_uniform_state_set3f (GskNglUniformState   *state,
 static inline void
 gsk_ngl_uniform_state_set4f (GskNglUniformState   *state,
                              GskNglUniformProgram *program,
-                             guint                 location,
+                             guint                 key,
                              guint                 stamp,
                              float                 value0,
                              float                 value1,
@@ -348,12 +316,12 @@ gsk_ngl_uniform_state_set4f (GskNglUniformState   *state,
                              float                 value3)
 {
   Uniform4f *u;
-  GskNglUniformInfoElement *info;
+  GskNglUniformMapping *info;
 
   g_assert (state != NULL);
   g_assert (program != NULL);
 
-  if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_4F, 1, location, stamp, &info)))
+  if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_4F, 1, key, stamp, &info)))
     {
       if (info->info.initial || u->v0 != value0 || u->v1 != value1 || u->v2 != value2 || u->v3 != value3)
         {
@@ -362,7 +330,7 @@ gsk_ngl_uniform_state_set4f (GskNglUniformState   *state,
           u->v1 = value1;
           u->v2 = value2;
           u->v3 = value3;
-          gsk_ngl_uniform_info_changed (info, location, stamp);
+          gsk_ngl_uniform_info_changed (info, stamp);
         }
     }
 }
@@ -370,23 +338,23 @@ gsk_ngl_uniform_state_set4f (GskNglUniformState   *state,
 static inline void
 gsk_ngl_uniform_state_set1ui (GskNglUniformState   *state,
                               GskNglUniformProgram *program,
-                              guint                 location,
+                              guint                 key,
                               guint                 stamp,
                               guint                 value0)
 {
   Uniform1ui *u;
-  GskNglUniformInfoElement *info;
+  GskNglUniformMapping *info;
 
   g_assert (state != NULL);
   g_assert (program != NULL);
 
-  if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_1UI, 1, location, stamp, &info)))
+  if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_1UI, 1, key, stamp, &info)))
     {
       if (info->info.initial || u->v0 != value0)
         {
           GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform1ui, 1);
           u->v0 = value0;
-          gsk_ngl_uniform_info_changed (info, location, stamp);
+          gsk_ngl_uniform_info_changed (info, stamp);
         }
     }
 }
@@ -394,23 +362,23 @@ gsk_ngl_uniform_state_set1ui (GskNglUniformState   *state,
 static inline void
 gsk_ngl_uniform_state_set1i (GskNglUniformState   *state,
                              GskNglUniformProgram *program,
-                             guint                 location,
+                             guint                 key,
                              guint                 stamp,
                              int                   value0)
 {
   Uniform1i *u;
-  GskNglUniformInfoElement *info;
+  GskNglUniformMapping *info;
 
   g_assert (state != NULL);
   g_assert (program != NULL);
 
-  if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_1I, 1, location, stamp, &info)))
+  if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_1I, 1, key, stamp, &info)))
     {
       if (info->info.initial || u->v0 != value0)
         {
           GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform1i, 1);
           u->v0 = value0;
-          gsk_ngl_uniform_info_changed (info, location, stamp);
+          gsk_ngl_uniform_info_changed (info, stamp);
         }
     }
 }
@@ -418,25 +386,25 @@ gsk_ngl_uniform_state_set1i (GskNglUniformState   *state,
 static inline void
 gsk_ngl_uniform_state_set2i (GskNglUniformState   *state,
                              GskNglUniformProgram *program,
-                             guint                 location,
+                             guint                 key,
                              guint                 stamp,
                              int                   value0,
                              int                   value1)
 {
   Uniform2i *u;
-  GskNglUniformInfoElement *info;
+  GskNglUniformMapping *info;
 
   g_assert (state != NULL);
   g_assert (program != NULL);
 
-  if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_2I, 1, location, stamp, &info)))
+  if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_2I, 1, key, stamp, &info)))
     {
       if (info->info.initial || u->v0 != value0 || u->v1 != value1)
         {
           GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform2i, 1);
           u->v0 = value0;
           u->v1 = value1;
-          gsk_ngl_uniform_info_changed (info, location, stamp);
+          gsk_ngl_uniform_info_changed (info, stamp);
         }
     }
 }
@@ -444,19 +412,19 @@ gsk_ngl_uniform_state_set2i (GskNglUniformState   *state,
 static inline void
 gsk_ngl_uniform_state_set3i (GskNglUniformState   *state,
                              GskNglUniformProgram *program,
-                             guint                 location,
+                             guint                 key,
                              guint                 stamp,
                              int                   value0,
                              int                   value1,
                              int                   value2)
 {
   Uniform3i *u;
-  GskNglUniformInfoElement *info;
+  GskNglUniformMapping *info;
 
   g_assert (state != NULL);
   g_assert (program != NULL);
 
-  if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_3I, 1, location, stamp, &info)))
+  if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_3I, 1, key, stamp, &info)))
     {
       if (info->info.initial || u->v0 != value0 || u->v1 != value1 || u->v2 != value2)
         {
@@ -464,7 +432,7 @@ gsk_ngl_uniform_state_set3i (GskNglUniformState   *state,
           u->v0 = value0;
           u->v1 = value1;
           u->v2 = value2;
-          gsk_ngl_uniform_info_changed (info, location, stamp);
+          gsk_ngl_uniform_info_changed (info, stamp);
         }
     }
 }
@@ -472,7 +440,7 @@ gsk_ngl_uniform_state_set3i (GskNglUniformState   *state,
 static inline void
 gsk_ngl_uniform_state_set4i (GskNglUniformState   *state,
                              GskNglUniformProgram *program,
-                             guint                 location,
+                             guint                 key,
                              guint                 stamp,
                              int                   value0,
                              int                   value1,
@@ -480,12 +448,12 @@ gsk_ngl_uniform_state_set4i (GskNglUniformState   *state,
                              int                   value3)
 {
   Uniform4i *u;
-  GskNglUniformInfoElement *info;
+  GskNglUniformMapping *info;
 
   g_assert (state != NULL);
   g_assert (program != NULL);
 
-  if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_4I, 1, location, stamp, &info)))
+  if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_4I, 1, key, stamp, &info)))
     {
       if (info->info.initial || u->v0 != value0 || u->v1 != value1 || u->v2 != value2 || u->v3 != value3)
         {
@@ -494,7 +462,7 @@ gsk_ngl_uniform_state_set4i (GskNglUniformState   *state,
           u->v1 = value1;
           u->v2 = value2;
           u->v3 = value3;
-          gsk_ngl_uniform_info_changed (info, location, stamp);
+          gsk_ngl_uniform_info_changed (info, stamp);
         }
     }
 }
@@ -502,24 +470,24 @@ gsk_ngl_uniform_state_set4i (GskNglUniformState   *state,
 static inline void
 gsk_ngl_uniform_state_set_rounded_rect (GskNglUniformState   *state,
                                         GskNglUniformProgram *program,
-                                        guint                 location,
+                                        guint                 key,
                                         guint                 stamp,
                                         const GskRoundedRect *rounded_rect)
 {
   GskRoundedRect *u;
-  GskNglUniformInfoElement *info;
+  GskNglUniformMapping *info;
 
   g_assert (state != NULL);
   g_assert (program != NULL);
   g_assert (rounded_rect != NULL);
 
-  if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_ROUNDED_RECT, 1, location, stamp, &info)))
+  if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_ROUNDED_RECT, 1, key, stamp, &info)))
     {
       if (info->info.initial || memcmp (u, rounded_rect, sizeof *u) != 0)
         {
           GSK_NGL_UNIFORM_STATE_REPLACE (info, u, GskRoundedRect, 1);
           memcpy (u, rounded_rect, sizeof *rounded_rect);
-          gsk_ngl_uniform_info_changed (info, location, stamp);
+          gsk_ngl_uniform_info_changed (info, stamp);
         }
     }
 }
@@ -527,24 +495,24 @@ gsk_ngl_uniform_state_set_rounded_rect (GskNglUniformState   *state,
 static inline void
 gsk_ngl_uniform_state_set_matrix (GskNglUniformState      *state,
                                   GskNglUniformProgram    *program,
-                                  guint                    location,
+                                  guint                    key,
                                   guint                    stamp,
                                   const graphene_matrix_t *matrix)
 {
   graphene_matrix_t *u;
-  GskNglUniformInfoElement *info;
+  GskNglUniformMapping *info;
 
   g_assert (state != NULL);
   g_assert (program != NULL);
   g_assert (matrix != NULL);
 
-  if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_MATRIX, 1, location, stamp, &info)))
+  if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_MATRIX, 1, key, stamp, &info)))
     {
       if (info->info.initial || memcmp (u, matrix, sizeof *u) != 0)
         {
           GSK_NGL_UNIFORM_STATE_REPLACE (info, u, graphene_matrix_t, 1);
           memcpy (u, matrix, sizeof *matrix);
-          gsk_ngl_uniform_info_changed (info, location, stamp);
+          gsk_ngl_uniform_info_changed (info, stamp);
         }
     }
 }
@@ -566,11 +534,11 @@ gsk_ngl_uniform_state_set_matrix (GskNglUniformState      *state,
 static inline void
 gsk_ngl_uniform_state_set_texture (GskNglUniformState   *state,
                                    GskNglUniformProgram *program,
-                                   guint                 location,
+                                   guint                 key,
                                    guint                 stamp,
                                    guint                 texture_slot)
 {
-  GskNglUniformInfoElement *info;
+  GskNglUniformMapping *info;
   guint *u;
 
   g_assert (texture_slot >= GL_TEXTURE0);
@@ -578,13 +546,13 @@ gsk_ngl_uniform_state_set_texture (GskNglUniformState   *state,
 
   texture_slot -= GL_TEXTURE0;
 
-  if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_TEXTURE, 1, location, stamp, &info)))
+  if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_TEXTURE, 1, key, stamp, &info)))
     {
       if (info->info.initial || *u != texture_slot)
         {
           GSK_NGL_UNIFORM_STATE_REPLACE (info, u, guint, 1);
           *u = texture_slot;
-          gsk_ngl_uniform_info_changed (info, location, stamp);
+          gsk_ngl_uniform_info_changed (info, stamp);
         }
     }
 }
@@ -603,18 +571,18 @@ gsk_ngl_uniform_state_set_texture (GskNglUniformState   *state,
 static inline void
 gsk_ngl_uniform_state_set_color (GskNglUniformState   *state,
                                  GskNglUniformProgram *program,
-                                 guint                 location,
+                                 guint                 key,
                                  guint                 stamp,
                                  const GdkRGBA        *color)
 {
   static const GdkRGBA transparent = {0};
-  GskNglUniformInfoElement *info;
+  GskNglUniformMapping *info;
   GdkRGBA *u;
 
   g_assert (state != NULL);
   g_assert (program != NULL);
 
-  if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_COLOR, 1, location, stamp, &info)))
+  if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_COLOR, 1, key, stamp, &info)))
     {
       if (color == NULL)
         color = &transparent;
@@ -623,7 +591,7 @@ gsk_ngl_uniform_state_set_color (GskNglUniformState   *state,
         {
           GSK_NGL_UNIFORM_STATE_REPLACE (info, u, GdkRGBA, 1);
           memcpy (u, color, sizeof *color);
-          gsk_ngl_uniform_info_changed (info, location, stamp);
+          gsk_ngl_uniform_info_changed (info, stamp);
         }
     }
 }
@@ -631,25 +599,25 @@ gsk_ngl_uniform_state_set_color (GskNglUniformState   *state,
 static inline void
 gsk_ngl_uniform_state_set1fv (GskNglUniformState   *state,
                               GskNglUniformProgram *program,
-                              guint                 location,
+                              guint                 key,
                               guint                 stamp,
                               guint                 count,
                               const float          *value)
 {
   Uniform1f *u;
-  GskNglUniformInfoElement *info;
+  GskNglUniformMapping *info;
 
   g_assert (state != NULL);
   g_assert (program != NULL);
   g_assert (count > 0);
 
-  if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_1FV, count, location, stamp, &info)))
+  if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_1FV, count, key, stamp, &info)))
     {
       if (info->info.initial || count != info->info.array_count || memcmp (u, value, sizeof *u * count) != 0)
         {
           GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform1f, count);
           memcpy (u, value, sizeof (Uniform1f) * count);
-          gsk_ngl_uniform_info_changed (info, location, stamp);
+          gsk_ngl_uniform_info_changed (info, stamp);
         }
     }
 }
@@ -657,25 +625,25 @@ gsk_ngl_uniform_state_set1fv (GskNglUniformState   *state,
 static inline void
 gsk_ngl_uniform_state_set2fv (GskNglUniformState   *state,
                               GskNglUniformProgram *program,
-                              guint                 location,
+                              guint                 key,
                               guint                 stamp,
                               guint                 count,
                               const float          *value)
 {
   Uniform2f *u;
-  GskNglUniformInfoElement *info;
+  GskNglUniformMapping *info;
 
   g_assert (state != NULL);
   g_assert (program != NULL);
   g_assert (count > 0);
 
-  if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_2FV, count, location, stamp, &info)))
+  if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_2FV, count, key, stamp, &info)))
     {
       if (info->info.initial || count != info->info.array_count || memcmp (u, value, sizeof *u * count) != 0)
         {
           GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform2f, count);
           memcpy (u, value, sizeof (Uniform2f) * count);
-          gsk_ngl_uniform_info_changed (info, location, stamp);
+          gsk_ngl_uniform_info_changed (info, stamp);
         }
     }
 }
@@ -683,25 +651,25 @@ gsk_ngl_uniform_state_set2fv (GskNglUniformState   *state,
 static inline void
 gsk_ngl_uniform_state_set3fv (GskNglUniformState   *state,
                               GskNglUniformProgram *program,
-                              guint                 location,
+                              guint                 key,
                               guint                 stamp,
                               guint                 count,
                               const float          *value)
 {
   Uniform3f *u;
-  GskNglUniformInfoElement *info;
+  GskNglUniformMapping *info;
 
   g_assert (state != NULL);
   g_assert (program != NULL);
   g_assert (count > 0);
 
-  if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_3FV, count, location, stamp, &info)))
+  if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_3FV, count, key, stamp, &info)))
     {
       if (info->info.initial || count != info->info.array_count || memcmp (u, value, sizeof *u * count) != 0)
         {
           GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform3f, count);
           memcpy (u, value, sizeof (Uniform3f) * count);
-          gsk_ngl_uniform_info_changed (info, location, stamp);
+          gsk_ngl_uniform_info_changed (info, stamp);
         }
     }
 }
@@ -709,25 +677,25 @@ gsk_ngl_uniform_state_set3fv (GskNglUniformState   *state,
 static inline void
 gsk_ngl_uniform_state_set4fv (GskNglUniformState   *state,
                               GskNglUniformProgram *program,
-                              guint                 location,
+                              guint                 key,
                               guint                 stamp,
                               guint                 count,
                               const float          *value)
 {
   Uniform4f *u;
-  GskNglUniformInfoElement *info;
+  GskNglUniformMapping *info;
 
   g_assert (state != NULL);
   g_assert (program != NULL);
   g_assert (count > 0);
 
-  if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_4FV, count, location, stamp, &info)))
+  if ((u = gsk_ngl_uniform_state_get_value (state, program, GSK_NGL_UNIFORM_FORMAT_4FV, count, key, stamp, &info)))
     {
       if (info->info.initial || count != info->info.array_count || memcmp (u, value, sizeof *u * count) != 0)
         {
           GSK_NGL_UNIFORM_STATE_REPLACE (info, u, Uniform4f, count);
           memcpy (u, value, sizeof (Uniform4f) * count);
-          gsk_ngl_uniform_info_changed (info, location, stamp);
+          gsk_ngl_uniform_info_changed (info, stamp);
         }
     }
 }